{# Sources into a collection, in steps (dialog body): its name (a new one only), the parts of this app to read (the twin knows each part's files, so nobody types a path; every part ticked to start), the file types to read of them (the loader's own ticked), files uploaded alongside, and a review of all of it with how much it is. Each step's answer shows beside it once passed. With ``name`` it adds to that collection. What it posts is what the API takes (``part``, ``extension``, ``file``). #} {% from "components/macros/layout.html" import dialog_title %} {% from "components/macros/form.html" import action, checkbox, field, file_button, form_footer, text_input, wizard, wizard_step %} {# Every one of ``ids`` (an Alpine expression) in ``key`` ticked, or none once all are: a group's one button, saying which it will do. #} {% macro all_or_none(label, key, ids, marker) %}{{ action(label, marker ~ " x-text=\"has('" ~ key ~ "', " ~ ids ~ ") ? 'None' : 'All'\" @click=\"flip('" ~ key ~ "', " ~ ids ~ ")\"") }}{% endmacro %} {# Each kind of part's ids, then every file type: what the All/None buttons flip. #} {% set groups = knowable.parts|map(attribute=1)|map("map", attribute=0)|map("list")|list %} {% set every_type = knowable.types|map(attribute=1)|sum(start=[]) %} {% set first = 0 if name else 1 %} {% set steps = ([] if name else [("Name", "title")]) + [("Source code", "partsSaid"), ("File types", "typesSaid"), ("Files", "filesSaid"), ("Review", None)] %} {{ dialog_title("Add to " ~ name if name else "New knowledge base", "What it holds: parts of this app, files of your own, or both.") }}